using UnityEngine;
using System;
using System.Collections;
 
#if UNITY_EDITOR
using UnityEditor;
[CustomPropertyDrawer(typeof(LabelAttribute))]
public class ConditionalHidePropertyDrawer : PropertyDrawer
{
    protected virtual bool GetConditionalHideAttributeResult(LabelAttribute condHAtt, SerializedProperty property)
    {
 
        string propertyPath = property.propertyPath;  
        string conditionPath = propertyPath.Replace(property.name, condHAtt.ConditionalSourceField); 
        SerializedProperty sourcePropertyValue = property.serializedObject.FindProperty(conditionPath);

        if (sourcePropertyValue != null)
        {
            if (condHAtt.type == 0)
            {
 
                return sourcePropertyValue.boolValue == condHAtt.condictionValue;
            }
            else
            {
                return sourcePropertyValue.intValue == condHAtt.condictionIntValue;
            }
        }
        return true;
    }
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        LabelAttribute condHAtt = (LabelAttribute)attribute;
        bool enabled = GetConditionalHideAttributeResult(condHAtt, property);
        if (enabled)
        {
            return BaseGetPropertyHeight(property, label);
        }
        else
        {
            return 0.1f;
        }
    }
    public  virtual float BaseGetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return EditorGUI.GetPropertyHeight(property, label);
    }

    public virtual void DrawPropertyItem(LabelAttribute condHAtt,Rect position, SerializedProperty property, GUIContent label)
    {

        GUI.SetNextControlName(condHAtt.ctrlName);

        if (condHAtt.condiction)
        {
            if (property.propertyType == SerializedPropertyType.Float)
            {
               
                EditorGUI.Slider(position, property, condHAtt.min, condHAtt.max, label);
                goto DrawPropertyItemCheckCtrlFocue;
            }
            else if (property.propertyType == SerializedPropertyType.Integer)
            {
                 
                EditorGUI.IntSlider(position, property, (int)condHAtt.min, (int)condHAtt.max, label);
                goto DrawPropertyItemCheckCtrlFocue;
            }
        }

        if (property.propertyType == SerializedPropertyType.Color)
        {
            EditorGUI.BeginChangeCheck();
            Color colorValue;
 
            colorValue = EditorGUI.ColorField(position, label, property.colorValue, true, condHAtt.showAlpha, condHAtt.isHDR);
            if (EditorGUI.EndChangeCheck())
            {
                property.colorValue = colorValue;
            }
        }
        else
        {
            
            EditorGUI.PropertyField(position, property, label, true);
        }
        DrawPropertyItemCheckCtrlFocue:
        if (  GUI.GetNameOfFocusedControl()== condHAtt.ctrlName)
        {
            CtrlNameAttribute.FocusedControl = condHAtt.ctrlName;
        }
         

    }
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        LabelAttribute condHAtt = (LabelAttribute)attribute;
        var targetObject = property.serializedObject.targetObject;
        var targetObjectClassType = targetObject.GetType();
        var field = targetObjectClassType.GetField(property.propertyPath);
        if (field != null)
        {
            object [] objs = field.GetCustomAttributes(false);
            for (int i = 0; i < objs.Length; i++)
            {
                var o = objs[i];
                if (o is UnityEngine.RangeAttribute)
                {
                    RangeAttribute ra = (RangeAttribute)o;

                    condHAtt.max = ra.max;
                    condHAtt.min = ra.min;
                    condHAtt.condiction = true;
                }
                if (o is  LabelRangeAttribute)
                {
                    LabelRangeAttribute ra = (LabelRangeAttribute)o;

                    condHAtt.max = ra.max;
                    condHAtt.min = ra.min;
                    condHAtt.condiction = true;
                }
                //
                if (o is ColorUsageAttribute)
                {
                    ColorUsageAttribute cs = (ColorUsageAttribute)o;
                    condHAtt.isHDR = cs.hdr;
                    condHAtt.showAlpha = cs.showAlpha;
                   
                }
                if (o is CtrlNameAttribute)
                {
                    CtrlNameAttribute cn = (CtrlNameAttribute)o;
                    condHAtt.ctrlName = cn.ctrlName;
                }
            }

        }
        if (null == condHAtt.ctrlName)
            condHAtt.ctrlName = "EDITOR_CTRL" + property.propertyPath;

        bool enabled = true;
        if(condHAtt.ctrlByParam)
            enabled = GetConditionalHideAttributeResult(condHAtt, property);
        bool wasEnabled = GUI.enabled;
        GUI.enabled = enabled;
        if ( enabled)
        {
            label.text = condHAtt.Label;
            
            DrawPropertyItem(condHAtt,position,property,label);
            
        }
        GUI.enabled = wasEnabled;
    }
}
#endif

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property |
    AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
public class CtrlNameAttribute : PropertyAttribute
{
    public static string FocusedControl;
    public string ctrlName;
    public CtrlNameAttribute(string ctrlName )
    {
        this.ctrlName = ctrlName;
    }
}


[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public sealed class LabelRangeAttribute : PropertyAttribute
{
    public  float min;
    public  float max;


    public LabelRangeAttribute(float min, float max)
    {
        this.min = min;
        this.max = max;
    }
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property |
    AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
public class LabelAttribute : PropertyAttribute
{
    public string ConditionalSourceField = "";
    public string Label = "";
    public bool condiction = false;
    public float max;
    public float min;
    public bool ctrlByParam = true;
    public int type = 0;
    public bool condictionValue = true;
    public int condictionIntValue = 0;

    public bool isHDR = false;
    public bool showAlpha = true;
    public string ctrlName=null;

    public LabelAttribute(string label,string conditionalSourceField)
    {
        type = 0;
        if (conditionalSourceField.StartsWith("!"))
        {
            this.ConditionalSourceField = conditionalSourceField.Substring(1);
            condictionValue = false;
        }
        else
        {
            this.ConditionalSourceField = conditionalSourceField;
            condictionValue = true;
        }
        this.Label = "    "+label;
        condiction = false;
        ctrlByParam = true;
    }

    public LabelAttribute(string label, string conditionalSourceField,int val)
    {
        type = 1;
        this.ConditionalSourceField = conditionalSourceField;
        condictionIntValue = val;
        condictionValue = true;
        this.Label = "    " + label;
        condiction = false;
        ctrlByParam = true;
    }


    public LabelAttribute(string label )
    {
        this.Label = label;
        condiction = false;
        this.ctrlByParam = false;
    }

}
